home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / dev / lang / pcq12src.lzh / Runtime / Readers / ReadReal.asm < prev    next >
Assembly Source File  |  1991-04-12  |  2KB  |  99 lines

  1.  
  2. *    ReadReal.asm
  3. *    of PCQ Pascal runtime library
  4. *    Copyright (c) 1989 Patrick Quaid
  5.  
  6. *    This routine just reads a real number from the given
  7. *    file in normal decimal form, i.e.
  8. *        {digit}[.{digit}]
  9. *
  10. *       It depends on ReadInt - ReadInt needs to return in d1
  11. *       a C style Boolean (i.e. 0 => false, other => true)
  12. *       that answers the eternal question "Is it minus?"
  13.  
  14.  
  15.     XREF    _p%ReadOneChar
  16.     XREF    _p%GetThatChar
  17.     XREF    _p%ReadInt
  18.     XREF    _p%IOResult
  19.  
  20.     XREF    _p%MathBase
  21.     XREF    _LVOSPAdd
  22.     XREF    _LVOSPMul
  23.     XREF    _LVOSPDiv
  24.     XREF    _LVOSPFlt
  25.     XREF    _LVOSPNeg
  26.  
  27.     SECTION    PCQ_Runtime,CODE
  28.  
  29.     XDEF    _p%ReadReal
  30. _p%ReadReal
  31.  
  32. *    At the outset the address of the real variable is in a0
  33. *    and the file record pointer is on the stack, at 4(sp)
  34.  
  35.     tst.l    _p%IOResult    ; is IO system OK?
  36.     bne    Out
  37.  
  38.     move.l    a0,-(sp)    ; save var address
  39.     move.l    8(sp),d0    ; get the file record ptr
  40.     move.l    d0,-(sp)    ; set up for next call
  41.     jsr    _p%ReadInt    ; get integer part
  42.     addq.l    #4,sp        ; pop stack
  43.  
  44.     tst.l    _p%IOResult    ; check again
  45.     bne    5$
  46.  
  47.     move.w  d1,-(sp)    ; save IsMinus
  48.     beq.s    4$        ; >= zero, so skip
  49.     neg.l    d0        ; take abs
  50. 4$
  51.     move.l    _p%MathBase,a6    ; get float value of int part
  52.     jsr    _LVOSPFlt(a6)    ; d0 = float of int part
  53.  
  54.     move.l    d0,-(sp)    ; save it
  55.     move.l    14(sp),a0    ; get file rec
  56.  
  57.     jsr    _p%ReadOneChar    ; read next char into d0
  58.     tst.l    _p%IOResult    ; did it go OK?
  59.     bne    1$        ; if not, leave
  60.     cmp.b    #'.',d0        ; is it a period?
  61.     bne    1$        ; if not, we're done already
  62.     jsr    _p%GetThatChar    ; if so, eat the decimal point
  63.     move.l    #$A0000044,-(sp) ; store 10.0
  64.  
  65. 2$    jsr    _p%ReadOneChar    ; get next char into d0
  66.     tst.l    _p%IOResult    ; did IO go OK?
  67.     bne    3$
  68.     cmp.b    #'0',d0        ; compare to '0'
  69.     blt    3$        ; not numeric
  70.     cmp.b    #'9',d0        ; 9
  71.     bgt    3$        ; skip
  72.     and.l    #$FF,d0        ; get char part
  73.     sub.b    #'0',d0        ; get value
  74.     move.l    _p%MathBase,a6
  75.     jsr    _LVOSPFlt(a6)    ; d0 := flt(c)
  76.     move.l    (sp),d1        ; d1 := divisor
  77.     jsr    _LVOSPDiv(a6)    ; d0 := flt(c) / divisor
  78.     move.l    4(sp),d1    ; d1 := r
  79.     jsr    _LVOSPAdd(a6)    ; d0 := r + (flt(c) / divisor)
  80.     move.l    d0,4(sp)    ; save it
  81.     move.l    (sp),d0        ; d0 := divisor
  82.     move.l    #$A0000044,d1    ; d1 := 10.0
  83.     jsr    _LVOSPMul(a6)    ; d0 := divisor * 10
  84.     move.l    d0,(sp)        ; save it
  85.     jsr    _p%GetThatChar    ; eat the character we just processed
  86.     bra    2$
  87.  
  88. 3$    addq.l    #4,sp        ; pop stack
  89. 1$    move.l    (sp)+,d0    ; pop final value
  90.     move.w    (sp)+,d1    ; pop sign
  91.     beq.s    5$        ; if positive, skip
  92.     move.l    _p%MathBase,a6
  93.     jsr    _LVOSPNeg(a6)    ; get -r
  94. 5$    move.l    (sp)+,a0    ; retrieve address
  95.     move.l    d0,(a0)        ; store final value
  96. Out    rts            ; and return
  97.  
  98.     END
  99.